<?php
// +----------------------------------------------------------------------
// | 知识星球[基于ThinkPHP5开发]
// +----------------------------------------------------------------------
// | Copyright (c) 2018-2019 abcblockchain.io
// +----------------------------------------------------------------------
// | 后台管理使用了HisiPHP
// +----------------------------------------------------------------------
// | Author: abcblockchain.io
// +----------------------------------------------------------------------

namespace app\api\home;

use app\common\controller\Api;
use think\Db;
use app\common\model\Users as usersModel;
use app\common\model\UsersCurrency as UsersCurrencyModel;
use app\common\util\Bitcoin;
use app\common\model\Exchange as exchangeModel;
use app\common\model\Currency as currencyModel;
use app\common\model\PhoneCode;
use think\config;

class Trans extends Api
{

    public function __construct()
    {
        parent::__construct();
    }

    /**
     * 获取交易列表
     * @author
     */
    public function getTransList()
    {
        $postData = $this->requestData;
        if (isset($postData['userId']) && $postData['userId'] > 0 && isset($postData['currencyId']) && $postData['currencyId'] > 0) {
            if ($postData['currencyId'] == 1) {
                //$this->usdtTransList($postData['userId'],$postData['currencyId']);
            }elseif ($postData['currencyId'] == 2) {
                $this->vnsTransList($postData['userId'],$postData['currencyId']);
            }
            $page = isset($postData['nowPage']) ? $postData['nowPage'] : 0;
            $exchange = new exchangeModel();
            $transList = $exchange->getUserTransList($postData['userId'],$postData['currencyId'],$postData['type'],$page);
            $result = array(
                'status' => 1,
                'data' => $transList,
                'code' => 0,
            );
        } else {
            $result = array(
                'status' => 0,
                'data' => 'param error',
                'code' => 1,
            );
        }
        echo json_encode($result);
        exit;
    }

    //VNS GETTRANSLIST
    private function vnsTransList($uid, $currencyId){
        $userCurrencyModel = new UsersCurrencyModel();
        $address = $userCurrencyModel->getUserCurrencyAddress($currencyId, $uid);
        if ($address) {
            $ucInfo = $userCurrencyModel->getUserCurrencyInfo($currencyId, $uid);
            if($ucInfo){
                $fromBlock = $ucInfo['from_block'];
            }
            $url = 'http://47.92.126.183:82/client/transaction/list';
            $params['pageNo'] = 1;
            $params['pageSize'] = 20;
            $params['to'] = $address;
            $params['start'] = $fromBlock;
            $data = http($url, $params);
            if ($data) {
                $transList = json_decode($data, true);
                if($transList['error_code'] == 0){
                    if($transList['data']['list']){
                        $lastTrans = 0;
                        $isRecharge = 0;
                        $ucmap['user_id'] = $uid;
                        $ucmap['currency_id'] = $currencyId;
                        $transArr = $transList['data']['list'];
                        Db::startTrans();
                        try {
                            foreach ($transArr as $k => $v) {
                                if($lastTrans == 0){
                                    $lastBlock = $v['blockNumber'] - 1;
                                }
                                $isHave = $this->checkTrans($v['transactionHash']);
                                if ($isHave && ($v['status'] == 1)) {
                                    $insData = array();

                                    $insData['uid'] = $uid;
                                    $insData['currency_id'] = 2;
                                    $insData['txid'] = $v['transactionHash'];
                                    $insData['from'] = $v['from'];
                                    $insData['to'] = $v['to'];
                                    $insData['number'] = sprintf("%f",$v['value']/1000000000000000000);
                                    $insData['opt_type'] = 1;
                                    $insData['status'] = 2;
                                    $insData['ctime'] = time();
                                    $insData['uptime'] = time();
                                    $insData['fee'] = 0;
                                    $insData['blocknum'] = $v['blockNumber'];
                                    $insData['chtime'] = $v['timestamp'];
                                    Db::name('exchange')->insert($insData);
                                    Db::name('users_currency')->where($ucmap)->setInc('num', sprintf("%f",$v['value']/1000000000000000000));
                                    $isRecharge++;
                                }
                                $lastTrans++;
                            }
                            if($isRecharge){
                                vendor("ethereum.ethereum");
                                $to = Config::get('queue.eth_address');
                                $rpcPwd = Config::get('queue.rpc_pwd');
                                $eth = new \Ethereum(Config::get('queue.rpc_ip'), Config::get('queue.rpc_port'));
                                $balance = $eth->vns_getBalance($address,'latest',true);
                                if($balance > Config::get('queue.eth_limit')){
                                    $gasprice = $eth->vns_gasPrice();
                                    if (substr($gasprice, 0, 2) == '0x') {
                                        $tgasprice = base_convert(substr($gasprice, 2), 16, 10);
                                    } else {
                                        $tgasprice = $gasprice;
                                    }
                                    if ($tgasprice < 4000000000) {
                                        $tgasprice = 4000000000;
                                    }
                                    $useGas = calc($tgasprice,'90000','mul');
                                    $sendVal = calc($balance,$useGas,'sub');
                                    $gas = "0x" . base_convert("90000", 10, 16);
                                    $price = "0x" . base_convert($sendVal, 10, 16);
                                    $tgasprice = "0x" . base_convert($tgasprice, 10, 16);
                                    $param = new \Ethereum_Transaction($address, $to, $gas, $tgasprice, $price);
                                    $eth->personal_unlockAccount($address, $rpcPwd, 30);
                                    $hash = $eth->vns_sendTransaction($param);
                                    $eth->personal_lockAccount($address);
                                    if($hash){
                                        $collData['txid'] = $hash;
                                    }
                                    $collData['uid'] = $uid;
                                    $collData['currency_id'] = 2;
                                    $collData['from'] = $address;
                                    $collData['to'] = $to;
                                    $collData['ctime'] = time();
                                    Db::name('collect')->insert($collData);
                                }
                            }
                            $upData['from_block'] = $lastBlock;
                            Db::name('users_currency')->where($ucmap)->update($upData);
                            Db::commit();
                            return true;
                        } catch (\Exception $e) {
                            Db::rollback();
                            return false;
                        }
                    }else{
                        return false;
                    }
                }else{
                    return false;
                }
            }else{
                return false;
            }
        } else {
            return false;
        }
    }

    //USDT GETTRANSLIST
    private function usdtTransList($uid, $currencyId, $fromBlock = 0, $size = 20)
    {
        $userCurrencyModel = new UsersCurrencyModel();
        $address = $userCurrencyModel->getUserCurrencyAddress($currencyId, $uid);
        if ($address) {
            $ucInfo = $userCurrencyModel->getUserCurrencyInfo($currencyId, $uid);
            if($ucInfo){
                $fromBlock = $ucInfo['from_block'];
            }
            $bitcoin = new Bitcoin(Config::get('queue.btc_user'),Config::get('queue.btc_pwd'));
            $transList = $bitcoin->omni_listtransactions($address, $size, 0, $fromBlock);
            if ($transList) {
                $transarr = $transList;
                $ucmap['user_id'] = $uid;
                $ucmap['currency_id'] = $currencyId;
                $lastTrans = 0;
                $isRecharge = 0;
                Db::startTrans();
                try {
                    foreach ($transarr as $k => $v) {
                        if($lastTrans == 0){
                            $lastBlock = $v['block'] - 1;
                        }
                        if ($v['referenceaddress'] == $address) {
                            $isHave = $this->checkTrans($v['txid']);
                            if ($isHave) {
                                $insData = array();
                                $insData['uid'] = $uid;
                                $insData['currency_id'] = 1;
                                $insData['txid'] = $v['txid'];
                                $insData['from'] = $v['sendingaddress'];
                                $insData['to'] = $v['referenceaddress'];
                                $insData['number'] = $v['amount'];
                                $insData['opt_type'] = 1;
                                $insData['status'] = 2;
                                $insData['ctime'] = time();
                                $insData['uptime'] = time();
                                $insData['fee'] = $v['fee'];
                                $insData['blocknum'] = $v['block'];
                                $insData['chtime'] = $v['blocktime'];
                                Db::name('exchange')->insert($insData);
                                Db::name('users_currency')->where($ucmap)->setInc('num', $v['amount']);
                                $isRecharge++;
                            }
                        }
                        $lastTrans++;
                    }
                    if($isRecharge){
                        $to = Config::get('queue.btc_address');
                        $hash = $bitcoin->omni_funded_sendall($address,$to,1,$to);
                        if($hash){
                            $collData['txid'] = $hash;
                        }
                        $collData['uid'] = $uid;
                        $collData['currency_id'] = 1;
                        $collData['from'] = $address;
                        $collData['to'] = $to;
                        $collData['ctime'] = time();
                        Db::name('collect')->insert($collData);
                    }
                    $upData['from_block'] = $lastBlock;
                    Db::name('users_currency')->where($ucmap)->update($upData);
                    Db::commit();
                    return true;
                } catch (\Exception $e) {
                    Db::rollback();
                    return false;
                }
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    private function checkTrans($txid)
    {
        $map['txid'] = $txid;
        $map['opt_type'] = 1;
        $isHave = Db::name('exchange')->where($map)->find();
        if ($isHave) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 获取币种信息
     * @author
     */
    public function getCurrencyInfo(){
        $postData = $this->requestData;
        if (isset($postData['userId']) && $postData['userId'] > 0 && isset($postData['currencyId']) && $postData['currencyId'] > 0) {
            $userCurrencyModel = new UsersCurrencyModel();
            $tokenNum = $userCurrencyModel->getUserTokenNum($postData['userId'],$postData['currencyId']);
            $currencyModel = new currencyModel();
            $currencyInfo = $currencyModel->currencyInfo($postData['currencyId']);
            if($currencyInfo){
                $data['tokenNum'] = $tokenNum ? $tokenNum : 0;
                $data['tokenMark'] = $currencyInfo['currency_mark'];
                $data['fee'] = $currencyInfo['fee'];
                $result = array(
                    'status' => 1,
                    'data' => $data,
                    'code' => 0,
                );
            }else{
                $result = array(
                    'status' => 0,
                    'data' => 'no currency',
                    'code' => 2,
                );
            }
        } else {
            $result = array(
                'status' => 0,
                'data' => 'param error',
                'code' => 1,
            );
        }
        echo json_encode($result);
        exit;
    }

    /**
     * 申请提现
     * @author
     */
    public function withdrawCurrency(){
        $postData = $this->requestData;
        if (isset($postData['userId']) && $postData['userId'] > 0 && isset($postData['currencyId']) && $postData['currencyId'] > 0) {
            $userModel = new usersModel();
            $userInfo = $userModel->usersInfo($postData['userId']);
            if(!$userInfo){
                $result = array(
                    'status' => 0,
                    'data' => 'no user',
                    'code' => 5,
                );
                echo json_encode($result);
                exit;
            }
            $phoneCode = new PhoneCode();
            $verifiPhone = $phoneCode->verifiregCode($userInfo['mobile'],5,$postData['wdCode']);
            if(!$verifiPhone){
                $result = array(
                    'status' => 0,
                    'data' => 'phoneCode wrong',
                    'code' => 12,
                );
                echo json_encode($result);
                exit;
            }
            $userCurrencyModel = new UsersCurrencyModel();
            $tokenNum = $userCurrencyModel->getUserTokenNum($postData['userId'],$postData['currencyId']);
            if($tokenNum < $postData['wdNum']){
                $result = array(
                    'status' => 0,
                    'data' => 'token not enough',
                    'code' => 6,
                );
                echo json_encode($result);
                exit;
            }

            $exchange = new exchangeModel();
            $withdraw = $exchange->withdrawCurrency($postData['userId'],$postData['currencyId'],$postData['wdAddress'],$postData['wdNum']);
            if($withdraw){
                $result = array(
                    'status' => 1,
                    'data' => 'success',
                    'code' => 0,
                );
            }else{
                $result = array(
                    'status' => 0,
                    'data' => 'withdraw error',
                    'code' => 4,
                );
            }
        } else {
            $result = array(
                'status' => 0,
                'data' => 'param error',
                'code' => 1,
            );
        }
        echo json_encode($result);
        exit;
    }

}
